package com.adouteam.simple.wechat.tool;

import com.adouteam.simple.wechat.base.Constant;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Http请求相关工具类
 *
 * @author buxianglong
 **/
public class HttpUtil{
    private static final Logger logger = LoggerFactory.getLogger(HttpUtil.class);

    private static final String HEAD_USER_AGENT = "User-Agent";
    private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36 AlexaToolbar/alxg-3.1";
    private static final String HEAD_REFER = "Referer";

    public static <T> T get(String url, Map<String, String> headerMaps, ResponseHandler<T> responseHandler){
        try(CloseableHttpClient httpClient = HttpClients.createDefault()){
            HttpGet httpGet = new HttpGet(url);
            fillCommonHeader(httpGet, url);
            fillHeader(httpGet, headerMaps);
            T responseBody = httpClient.execute(httpGet, responseHandler);
            logger.debug(Constant.LOGGER_PREFIX + "ResponseBody:" + responseBody.toString());
            return responseBody;
        }catch(IOException ioe){
            logger.error(Constant.LOGGER_PREFIX + "Exception when execute get request.", ioe);
        }
        return null;
    }

    public static <T> T postForm(String url, Map<String, String> headerMaps, Map<String, String> formBody, ResponseHandler<T> responseHandler){
        HttpPost httpPost = new HttpPost(url);
        fillCommonHeader(httpPost, url);
        fillHeader(httpPost, headerMaps);
        List<NameValuePair> nameValuePairs = null;
        if(null != formBody){
            nameValuePairs = new ArrayList<>();
            for(Map.Entry<String, String> entry : formBody.entrySet()){
                nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
        }

        try(CloseableHttpClient httpClient = HttpClients.createDefault()){
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            T responseBody = httpClient.execute(httpPost, responseHandler);
            logger.debug(Constant.LOGGER_PREFIX + "ResponseBody:" + responseBody.toString());
            return responseBody;
        }catch(IOException ioe){
            logger.error(Constant.LOGGER_PREFIX + "Exception when execute post request.", ioe);
        }
        return null;
    }

    public static <T> T post(String url, Map<String, String> headerMaps, HttpEntity httpEntity, ResponseHandler<T> responseHandler){
        HttpPost httpPost = new HttpPost(url);
        fillCommonHeader(httpPost, url);
        fillHeader(httpPost, headerMaps);
        try(CloseableHttpClient httpClient = HttpClients.createDefault()){
            httpPost.setEntity(httpEntity);
            T responseBody = httpClient.execute(httpPost, responseHandler);
            logger.debug(Constant.LOGGER_PREFIX + "ResponseBody:" + responseBody.toString());
            return responseBody;
        }catch(IOException ioe){
            logger.error(Constant.LOGGER_PREFIX + "Exception when execute post request.", ioe);
        }
        return null;
    }

    /**
     * 填充公共header
     *
     * @param httpRequestBase 请求对象
     * @param requestUrl      请求url
     */
    private static void fillCommonHeader(HttpRequestBase httpRequestBase, String requestUrl){
        Map<String, String> headerMaps = new HashMap<>();
        headerMaps.put(HEAD_USER_AGENT, USER_AGENT);
        if(StringUtils.isNotBlank(requestUrl)){
            headerMaps.put(HEAD_REFER, requestUrl);
        }
        fillHeader(httpRequestBase, headerMaps);
    }

    /**
     * 填充自定义header
     *
     * @param httpRequestBase 请求对象
     * @param headerMaps      自定义头部键值对
     */
    private static void fillHeader(HttpRequestBase httpRequestBase, Map<String, String> headerMaps){
        if(null == httpRequestBase){
            return;
        }
        if(null == headerMaps){
            return;
        }
        for(Map.Entry<String, String> entry : headerMaps.entrySet()){
            httpRequestBase.setHeader(entry.getKey(), entry.getValue());
        }
    }
}
